package socket

import (
	"card/app/framework/poker"
	"card/pkg/logger"
	"github.com/duke-git/lancet/v2/slice"
	"github.com/pkg/errors"
	"go.uber.org/zap"
	"sync"
	"time"
)

type Base struct {
	BaseScore   int
	BottomCards []poker.Poker
}
type RoomList struct {
	sync.RWMutex
	Room          map[string][]*Client
	KickSchedules map[*Client]*time.Timer
	Base          map[string]Base
}

var roomList *RoomList

func init() {
	roomList = new(RoomList)
	roomList.Room = make(map[string][]*Client, 0)
	roomList.Base = make(map[string]Base)
}
func (r *RoomList) Set(roomNum string, client *Client) {
	defer r.Unlock()
	r.Lock()
	data, ok := r.Room[roomNum]
	if !ok {
		data = make([]*Client, 0)
	}
	data = append(data, client)
	r.Room[roomNum] = data
}

func (r *RoomList) CheckUserExists(client *Client) error {
	defer r.Unlock()
	r.Lock()
	for _, v := range r.Room {
		if slice.Contain(v, client) {
			return errors.New("你已经存在其他房间")
		}
	}
	return nil
}

func (r *RoomList) Get(roomNum string) ([]*Client, error) {
	defer r.Unlock()
	r.Lock()
	data, ok := r.Room[roomNum]
	if !ok {
		return nil, errors.New("没有该房间")
	}
	return data, nil
}

func (r *RoomList) Delete(roomNum string, client *Client) error {
	defer r.Unlock()
	r.Lock()
	data, ok := r.Room[roomNum]
	if !ok {
		return errors.New("没有该房间")
	}
	data = slice.Filter(data, func(index int, item *Client) bool {
		return item != client
	})
	r.Room[roomNum] = data
	return nil
}

func (r *RoomList) GetClientsExceptSelf(roomNum string, client *Client) ([]*Client, error) {
	defer r.Unlock()
	r.Lock()
	data, ok := r.Room[roomNum]
	if !ok {
		return nil, errors.New("没有该房间")
	}
	data = slice.Filter(data, func(index int, item *Client) bool {
		return item != client
	})
	return data, nil
}

func (r *RoomList) Destroy(roomNum string) error {
	defer r.Unlock()
	r.Lock()
	_, ok := r.Room[roomNum]
	if !ok {
		return errors.New("没有该房间")
	}
	delete(r.Room, roomNum)
	return nil
}

func (r *RoomList) AddKickScheduleEvent(roomNum string, client *Client) {
	r.Lock()
	defer r.Unlock()
	t, ok := r.KickSchedules[client]
	if ok {
		t.Stop()
		delete(r.KickSchedules, client)
	}
	r.KickSchedules[client] = time.AfterFunc(30*time.Second, func() {
		//取消定时任务
		timer, ok := r.KickSchedules[client]
		if ok {
			timer.Stop()
			delete(r.KickSchedules, client)
		}
		if !client.Player.GetReadyStatus() {
			r.Delete(roomNum, client)
			clients, err := r.Get(roomNum)
			if err != nil {
				logger.Warn(nil, "[kick]", zap.Error(err))
			}
			if len(clients) == 0 {
				r.Destroy(roomNum)
				r.CancelAllScheduler(roomNum)
			}
		}
	})
}

func (r *RoomList) CancelAllScheduler(roomNum string) error {
	defer r.Unlock()
	r.Lock()
	data, ok := r.Room[roomNum]
	if !ok {
		return errors.New("没有该房间")
	}
	//需要将房间所有的任务 都取消掉
	for _, client := range data {
		//取消定时任务
		timer, ok := r.KickSchedules[client]
		if ok {
			timer.Stop()
			delete(r.KickSchedules, client)
		}
	}
	return nil
}
